package com.itheima.blog.admin.aop;

import com.google.common.base.Stopwatch;
import com.itheima.blog.admin.entity.TLog;
import com.itheima.blog.admin.service.ITLogService;
import com.itheima.blog.util.UserThreadLocalUtils;
import com.itheima.common.utills.AddressUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  AOP方法增强保存操作日志
 * </p>
 *
 * @author JXP
 * @since 2023-07-12
 */
@Aspect
@Component
@Slf4j
public class SysLogAspect {

    @Autowired
    private ITLogService logService;

    //定义切点 @Pointcut
    //在注解的位置切入代码
    @Pointcut("@annotation( com.itheima.blog.admin.aop.MyLog)")
    public void logPoinCut() {
    }

    //切面 配置通知
    @Around("logPoinCut()")
    public void saveSysLog(JoinPoint joinPoint) throws Exception {
        Stopwatch stopwatch = Stopwatch.createStarted();

        // 获取管理端用户Id
        Integer adminUserId = UserThreadLocalUtils.getAdminUserId();
        // 获取请求
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //保存日志
        TLog sysLog = new TLog();

        //从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取切入点所在的方法
        Method method = signature.getMethod();

        //获取用户id
        sysLog.setUserId(1L);
        if (adminUserId != null)
            sysLog.setUserId(adminUserId.longValue());
        // 获取请求URL
        sysLog.setRequestPath(request.getRequestURL().toString());

        // 获取接口名
        MyLog myLog = method.getAnnotation(MyLog.class);
        if (myLog != null) {
            String value = myLog.value();
            // 方法名
            sysLog.setRequestName(value);
        }else {
            // 如果未写value 默认方法名
            String methodName = method.getName();
            sysLog.setRequestName(methodName);
        }

        //获取用户ip地址
        String ip = request.getRemoteAddr();
        sysLog.setIp(ip);

        // ip来源
        String addressByIP = AddressUtil.getAddressByIP(ip);
        sysLog.setIpAdder(addressByIP);

        // 创建时间
        sysLog.setCreateTime(LocalDateTime.now());

        sysLog.setRequestType(request.getMethod());
        //TODO  状态
        sysLog.setState(attributes.getResponse().getStatus());

        stopwatch.stop();
        long timeConsuming = stopwatch.elapsed(TimeUnit.MILLISECONDS);
        sysLog.setRequestTime(timeConsuming);
        //调用service保存SysLog实体类到数据库
        logService.save(sysLog);
    }


}